/**
 * Copyright 2018 人人开源 http://www.renren.io
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package io.renren.modules.sys.controller;


import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.google.code.kaptcha.Constants;
import com.google.code.kaptcha.Producer;
import io.renren.common.utils.R;
import io.renren.modules.sys.entity.SysEmailEntity;
import io.renren.modules.sys.entity.SysUserEntity;
import io.renren.modules.sys.service.SysDeptService;
import io.renren.modules.sys.service.SysEmailService;
import io.renren.modules.sys.service.SysUserService;
import io.renren.modules.sys.shiro.ShiroUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 登录相关
 * 
 * @author chenshun
 * @email sunlightcs@gmail.com
 * @date 2016年11月10日 下午1:15:31
 */
@Controller
public class SysLoginController {
	@Autowired
	private Producer producer;
	@Autowired
	private SysDeptService sysDeptService;
	@Autowired
	private SysUserService sysUserService;
	@Autowired
	private SysEmailService sysEmailService;
	
	@RequestMapping("captcha.jpg")
	public void captcha(HttpServletResponse response)throws IOException {
        response.setHeader("Cache-Control", "no-store, no-cache");
        response.setContentType("image/jpeg");

        //生成文字验证码
        String text = producer.createText();
        //生成图片验证码
        BufferedImage image = producer.createImage(text);
        //保存到shiro session
        ShiroUtils.setSessionAttribute(Constants.KAPTCHA_SESSION_KEY, text);
        
        ServletOutputStream out = response.getOutputStream();
        ImageIO.write(image, "jpg", out);
	}
	
	/**
	 * 登录
	 */
	@ResponseBody
	@RequestMapping(value = "/sys/login", method = RequestMethod.POST)
	public R login(String username, String password, String captcha) {
		String kaptcha = ShiroUtils.getKaptcha(Constants.KAPTCHA_SESSION_KEY);
		if(!captcha.equalsIgnoreCase(kaptcha)){
			return R.error("验证码不正确");
		}
		
		try{
			Subject subject = ShiroUtils.getSubject();
			UsernamePasswordToken token = new UsernamePasswordToken(username, password);
			subject.login(token);
		}catch (UnknownAccountException e) {
			return R.error(e.getMessage());
		}catch (IncorrectCredentialsException e) {
			return R.error("账号或密码不正确");
		}catch (LockedAccountException e) {
			return R.error("账号已被锁定,请联系管理员");
		}catch (AuthenticationException e) {
			return R.error("账户验证失败");
		}
	    
		return R.ok();
	}
	
	/**
	 * 退出
	 */
	@RequestMapping(value = "logout", method = RequestMethod.GET)
	public String logout() {
		ShiroUtils.logout();
		return "redirect:login.html";
	}

	/**
	 * 注册
	 */
	@ResponseBody
	@RequestMapping(value = "/sys/register", method = RequestMethod.POST)
	public R register(String username, String password, String email) {
		try{
			SysUserEntity sysUserEntity = sysUserService.selectOne(new EntityWrapper<SysUserEntity>()
					.eq("username",username)
					.eq("status",1)
			);
			if(sysUserEntity != null){
				return R.error("该账号已被注册");
			}
			SysUserEntity userEntity = new SysUserEntity();
			userEntity.setDeptId(5L);
			userEntity.setEmail(email);
			userEntity.setUsername(username);
			userEntity.setPassword(password);
			List<Long> roleIdList = new ArrayList<>();
			roleIdList.add(1L);
			userEntity.setRoleIdList(roleIdList);
			sysUserService.save(userEntity);
		}catch (Exception e) {
			e.printStackTrace();
			return R.error("注册异常");
		}
		return R.ok();
	}

	/**
	 * 忘记密码之修改密码
	 */
	@ResponseBody
	@RequestMapping(value = "/sys/forget", method = RequestMethod.POST)
	public R forget(String username, String password, String code) {
		try{
			SysUserEntity sysUserEntity = sysUserService.selectOne(new EntityWrapper<SysUserEntity>()
					.eq("username",username)
					.eq("status",1)
			);
			if(sysUserEntity == null){
				return R.error("该账号不存在");
			}
			SysEmailEntity sysEmailEntity = sysEmailService.selectOne(new EntityWrapper<SysEmailEntity>()
					.eq("user_id",sysUserEntity.getUserId())
					.eq("code",code)
			);
			if (sysEmailEntity==null){
				return R.error("请输入正确的验证码");
			}
			if (sysEmailEntity.getUseful()==1){
				return R.error("验证码已使用,请重新获取验证码");
			}
			Date update = sysEmailEntity.getUpdateTime();
			int i = new Date().compareTo(update);
			if (i>0){
				return R.error("验证码已失效,请重新获取验证码");
			}
			String newPassword = ShiroUtils.sha256(password, sysUserEntity.getSalt());
			sysUserEntity.setPassword(newPassword);
			sysUserService.updateById(sysUserEntity);
			sysEmailEntity.setUseful(1);
			sysEmailService.updateById(sysEmailEntity);
		}catch (Exception e) {
			e.printStackTrace();
			return R.error("修改异常");
		}
		return R.ok();
	}
}
